package com.ruoyi.controller;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo;
import cn.binarywang.wx.miniapp.bean.WxMaUserInfo;
import cn.binarywang.wx.miniapp.util.WxMaConfigHolder;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.constant.BusinessConstant;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.framework.web.service.SysLoginService;
import com.ruoyi.common.utils.http.ResponseUtils;
import com.ruoyi.common.utils.socket.WebSocketHandler;
import com.ruoyi.service.SysUserServiceImpl;
import jakarta.servlet.http.HttpServletResponse;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.api.WxConsts;
import me.chanjar.weixin.common.bean.WxOAuth2UserInfo;
import me.chanjar.weixin.common.bean.oauth2.WxOAuth2AccessToken;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.io.IOException;
import java.util.Map;

@Slf4j
@RestController("微信")
@RequestMapping("/wx/user/{appid}")
public class WeixinController {

    @Autowired
    private WxMaService wxMaService;

    @Autowired
    private WxMpService wxMpService;
    @Autowired
    private SysLoginService sysLoginService;
    @Autowired
    private SysUserServiceImpl userService;

    @GetMapping("/authorize")
    public void authorize(HttpServletResponse response) throws IOException {
        String redirectUri = RuoYiConfig.getUploadBasePath() + "/wx/callback"; // 替换为你的回调地址
        String url = wxMpService.getOAuth2Service().buildAuthorizationUrl(redirectUri, WxConsts.OAuth2Scope.SNSAPI_USERINFO, null);
        response.sendRedirect(url);
    }

    @RequestMapping("/callback")
    public void callback(@PathVariable String appid, @RequestParam("code") String code, @RequestParam("userId") Long userId, HttpServletResponse response) throws WxErrorException, IOException {
        wxMpService.switchover(appid);
        WxOAuth2AccessToken wxMpOAuth2AccessToken = wxMpService.getOAuth2Service().getAccessToken(code);
        String openId = wxMpOAuth2AccessToken.getOpenId();
        // 将OpenID保存到session中或者返回前端
        // 假设保存到session
        System.out.println("openId: " + openId + ",userId:" + userId);
        userService.buildOpenId(userId, openId);
        WebSocketHandler.sendUser(String.valueOf(userId), "绑定成功");
        // 重定向到绑定页面
        ResponseUtils.writeMobileHtml(response, ResponseUtils.mobileText("绑定成功"));
        //response.sendRedirect("/bind.html"); // 替换为你的绑定页面地址

    }

    /**
     * 登陆接口
     */
    @RequestMapping("/login")
    public Object login(@PathVariable String appid, String code) {
        if (StrUtil.isBlank(code)) {
            return "empty jscode";
        }

        if (!wxMpService.switchover(appid)) {
            throw new IllegalArgumentException(String.format("111未找到对应appid=[%s]的配置，请核实！", appid));
        }

        try {
            WxOAuth2AccessToken session = wxMpService.getOAuth2Service().getAccessToken(code);
            //TODO 可以增加自己的逻辑，关联业务相关数据
            Map rs = sysLoginService.loginByOpenid(session.getOpenId(), BusinessConstant.UserType.CLIENT);
            return rs;
        } catch (WxErrorException e) {
            log.error(e.getMessage(), e);
            Assert.isFalse(true, e.getMessage());
            return e.toString();
        } finally {
            WxMaConfigHolder.remove();//清理ThreadLocal
        }
    }


    /**
     * <pre>
     * 获取用户信息接口
     * </pre>
     */
    @RequestMapping("/info")
    public Object info(@PathVariable String appid, String sessionKey,
                       String signature, String rawData, String encryptedData, String iv) {
        if (!wxMaService.switchover(appid)) {
            throw new IllegalArgumentException(String.format("未找到对应appid=[%s]的配置，请核实！", appid));
        }

        // 用户信息校验
        if (!wxMaService.getUserService().checkUserInfo(sessionKey, rawData, signature)) {
            WxMaConfigHolder.remove();//清理ThreadLocal
            return "user check failed";
        }

        // 解密用户信息
        WxMaUserInfo userInfo = wxMaService.getUserService().getUserInfo(sessionKey, encryptedData, iv);
        WxMaConfigHolder.remove();//清理ThreadLocal
        return userInfo;
    }

    /**
     * <pre>
     * 获取用户绑定手机号信息
     * </pre>
     */
    @RequestMapping("/phone")
    public Object phone(@PathVariable String appid, String code) throws WxErrorException {
        if (!wxMaService.switchover(appid)) {
            throw new IllegalArgumentException(String.format("未找到对应appid=[%s]的配置，请核实！", appid));
        }
        // 解密
        WxMaPhoneNumberInfo phoneNoInfo = wxMaService.getUserService().getPhoneNumber(code);

        WxMaConfigHolder.remove();//清理ThreadLocal
        userService.updatePhone(phoneNoInfo.getPhoneNumber());
        return phoneNoInfo;
    }


    /**
     * 用户登录接口
     * 1、如果用户存在，则登录。如果不存在，则返回错误信息
     */
    @SneakyThrows
    @RequestMapping("/mp/getUserInfo")
    public WxOAuth2UserInfo greetUser(@PathVariable String appid, @RequestParam String code) throws Exception {
        if (!this.wxMpService.switchover(appid)) {
            throw new IllegalArgumentException(String.format("未找到对应appid=[%s]的配置，请核实！", appid));
        }
        WxOAuth2AccessToken accessToken = wxMpService.getOAuth2Service().getAccessToken(code);
        WxOAuth2UserInfo user = wxMpService.getOAuth2Service().getUserInfo(accessToken, null);
        return user;
    }

    /**
     * 供应商登录接口
     * openId
     * userName
     * password
     * avatar
     */
    @SneakyThrows
    @RequestMapping(value = "/supplier/login")
    public Map<Object, Object> supplierLogin(@RequestBody SysUser user) throws Exception {
        return sysLoginService.supplierLogin(user);
    }


}
